CDKで複数スタックの並行デプロイを行ってみた
こんにちは、データアナリティクス事業本部の八木です。
何かしらの処理を行うとき、並列・並行実行して高速化したい!と思うのはエンジニアの常ではないでしょうか?
今回はAWS CDKで複数スタックを並行デプロイする方法についてご紹介します。
先にまとめ
- concurrencyオプションで複数スタックの並行デプロイができる
- 並行デプロイ数は指定が可能
- スタック間に依存関係がある場合は自動的に解決される
AWS CDKのconcurrencyオプションについて
2022年8月にconcurrencyオプションが追加されました。(v2.39.0)
ヘルプコマンドを実行すると、オプションの内容が確認できます。
$ cdk deploy --help cdk deploy [STACKS..] Deploys the stack(s) named STACKS into your AWS account Options: 〜〜(中略)〜〜 --concurrency Maximum number of simultaneous deployments (dependency permitting) to execute. [number] [default: 1] 〜〜(後略)〜〜
これはCDKアプリケーション内に複数のスタックが含まれる場合、依存関係を解決しつつ、並行デプロイをしてくれるオプションです。
--concurrency
のあとに数字を指定し、最大並行数を指定できます。
従来は複数スタックのデプロイは直列のみ可能となっており、並列実行したい場合はコマンドを呼び出す側で対応する必要がありましたが、このオプションによりCDK単体での実行が可能になりました。
やってみた
実際に動かして動作を確認してみます。
前提
- AWS CDK v2.68.0
- 各フェーズごとに
cdk destroy
でリソースを削除している
スタックの直列デプロイ
まず、以下のような3つのスタックが存在する状態で、通常通りデプロイを行ってみます。
import * as cdk from "aws-cdk-lib"; import { Construct } from "constructs"; import * as ec2 from "aws-cdk-lib/aws-ec2"; import * as dynamo from "aws-cdk-lib/aws-dynamodb"; export class SampleStack1 extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new ec2.Vpc(this, "VPC_A", { ipAddresses: ec2.IpAddresses.cidr("10.1.0.0/16"), subnetConfiguration: [ { cidrMask: 24, name: "public", subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: "private", subnetType: ec2.SubnetType.PRIVATE_ISOLATED, }, ], }); } } export class SampleStack2 extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new dynamo.Table(this, "SampleTable1", { tableName: "SampleTable1", billingMode: dynamo.BillingMode.PAY_PER_REQUEST, partitionKey: { name: "id", type: dynamo.AttributeType.STRING, }, removalPolicy: cdk.RemovalPolicy.DESTROY, }); } } export class SampleStack3 extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new dynamo.Table(this, "SampleTable2", { tableName: "SampleTable2", billingMode: dynamo.BillingMode.PAY_PER_REQUEST, partitionKey: { name: "id", type: dynamo.AttributeType.STRING, }, removalPolicy: cdk.RemovalPolicy.DESTROY, }); } }
#!/usr/bin/env node import "source-map-support/register"; import * as cdk from "aws-cdk-lib"; import { SampleStack1, SampleStack2, SampleStack3, } from "../lib/cdk-multi-deploy-sample-stack"; const app = new cdk.App(); new SampleStack1(app, "SampleStack1"); new SampleStack2(app, "SampleStack2"); new SampleStack3(app, "SampleStack3");
$ cdk deploy --all ✨ Synthesis time: 3.05s SampleStack1: building assets... [0%] start: Building db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region [100%] success: Built db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region SampleStack1: assets built SampleStack2: building assets... [0%] start: Building 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region [100%] success: Built 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region SampleStack2: assets built SampleStack3: building assets... [0%] start: Building 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region [100%] success: Built 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region SampleStack3: assets built SampleStack1 SampleStack1: deploying... [1/3] [0%] start: Publishing db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region [100%] success: Published db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region SampleStack1: creating CloudFormation changeset... ✅ SampleStack1 ✨ Deployment time: 78.81s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack1/dd5a3a30-d1bf-11ed-8a0d-0a9717c6da5d ✨ Total time: 81.86s SampleStack2 SampleStack2: deploying... [2/3] [0%] start: Publishing 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region [100%] success: Published 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region SampleStack2: creating CloudFormation changeset... ✅ SampleStack2 ✨ Deployment time: 38.22s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack2/0e9bc910-d1c0-11ed-a967-12981ec870d5 ✨ Total time: 41.27s SampleStack3 SampleStack3: deploying... [3/3] [0%] start: Publishing 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region [100%] success: Published 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region SampleStack3: creating CloudFormation changeset... ✅ SampleStack3 ✨ Deployment time: 39.07s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack3/276bdde0-d1c0-11ed-b63f-0a3c80fd2065 ✨ Total time: 42.12s
何もオプションを指定しない場合、3つのスタックは直列でデプロイされ、合計で約3分かかっています。
並行デプロイの場合(上限並行数>=スタック数)
続いて、同じリソースを並行デプロイしてみます。concurrencyオプションで並行デプロイスタック数の上限を3とします。
$ cdk deploy --all --concurrency 3 ✨ Synthesis time: 2.91s SampleStack1: building assets... [0%] start: Building db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region [100%] success: Built db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region SampleStack1: assets built SampleStack2: building assets... [0%] start: Building 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region [100%] success: Built 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region SampleStack2: assets built SampleStack3: building assets... [0%] start: Building 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region [100%] success: Built 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region SampleStack3: assets built SampleStack1 SampleStack2 SampleStack3 SampleStack3: deploying... [3/3] SampleStack2: deploying... [2/3] SampleStack1: deploying... [1/3] [0%] start: Publishing 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region [0%] start: Publishing 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region [0%] start: Publishing db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region [100%] success: Published 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region [100%] success: Published 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region [100%] success: Published db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region SampleStack3: creating CloudFormation changeset... SampleStack2: creating CloudFormation changeset... SampleStack1: creating CloudFormation changeset... SampleStack2 | 0/3 | 10:48:43 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack2 User Initiated SampleStack2 | 0/3 | 10:48:51 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack2 User Initiated SampleStack2 | 0/3 | 10:48:55 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack2 | 0/3 | 10:48:55 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable1 (SampleTable1E3EC8AE3) SampleStack2 | 0/3 | 10:48:56 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated SampleStack2 | 0/3 | 10:48:56 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable1 (SampleTable1E3EC8AE3) Resource creation Initiated SampleStack2 | 1/3 | 10:48:56 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack3 | 0/3 | 10:48:43 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack3 User Initiated SampleStack3 | 0/3 | 10:48:51 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack3 User Initiated SampleStack3 | 0/3 | 10:48:55 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack3 | 0/3 | 10:48:55 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable2 (SampleTable283919C1B) SampleStack3 | 0/3 | 10:48:57 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable2 (SampleTable283919C1B) Resource creation Initiated SampleStack1 | 0/19 | 10:48:43 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack1 User Initiated SampleStack1 | 0/19 | 10:48:51 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack1 User Initiated SampleStack1 | 0/19 | 10:48:55 | CREATE_IN_PROGRESS | AWS::EC2::VPC | VPC_A (VPCAEF14CDB5) SampleStack1 | 0/19 | 10:48:55 | CREATE_IN_PROGRESS | AWS::EC2::InternetGateway | VPC_A/IGW (VPCAIGW75D87454) SampleStack1 | 0/19 | 10:48:56 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack1 | 0/19 | 10:48:57 | CREATE_IN_PROGRESS | AWS::EC2::VPC | VPC_A (VPCAEF14CDB5) Resource creation Initiated SampleStack3 | 0/3 | 10:48:57 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated SampleStack3 | 1/3 | 10:48:57 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack1 | 0/19 | 10:48:57 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated SampleStack1 | 0/19 | 10:48:57 | CREATE_IN_PROGRESS | AWS::EC2::InternetGateway | VPC_A/IGW (VPCAIGW75D87454) Resource creation Initiated SampleStack1 | 1/19 | 10:48:57 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack2 | 2/3 | 10:49:07 | CREATE_COMPLETE | AWS::DynamoDB::Table | SampleTable1 (SampleTable1E3EC8AE3) SampleStack2 | 3/3 | 10:49:08 | CREATE_COMPLETE | AWS::CloudFormation::Stack | SampleStack2 SampleStack3 | 2/3 | 10:49:08 | CREATE_COMPLETE | AWS::DynamoDB::Table | SampleTable2 (SampleTable283919C1B) SampleStack3 | 3/3 | 10:49:09 | CREATE_COMPLETE | AWS::CloudFormation::Stack | SampleStack3 SampleStack1 | 2/19 | 10:49:08 | CREATE_COMPLETE | AWS::EC2::VPC | VPC_A (VPCAEF14CDB5) ✅ SampleStack3 ✨ Deployment time: 34.94s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack3/aa1af4a0-d1c1-11ed-910f-0ae4419fb0f9 ✨ Total time: 37.85s ✅ SampleStack2 ✨ Deployment time: 34.94s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack2/aa2247a0-d1c1-11ed-be03-0ee030fcd94b ✨ Total time: 37.85s SampleStack1 | 2/19 | 10:49:09 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet1/RouteTable (VPCAprivateSubnet1RouteTableE655FC72) SampleStack1 | 2/19 | 10:49:10 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet1/RouteTable (VPCApublicSubnet1RouteTable2C204262) SampleStack1 | 2/19 | 10:49:10 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet2/Subnet (VPCApublicSubnet2Subnet8E975B94) SampleStack1 | 2/19 | 10:49:10 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet2/RouteTable (VPCApublicSubnet2RouteTable2008F73C) SampleStack1 | 2/19 | 10:49:10 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet2/RouteTable (VPCAprivateSubnet2RouteTable796E6A86) SampleStack1 | 2/19 | 10:49:10 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet2/Subnet (VPCAprivateSubnet2SubnetEF69CD95) SampleStack1 | 2/19 | 10:49:10 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet1/Subnet (VPCApublicSubnet1SubnetCAE91A96) SampleStack1 | 2/19 | 10:49:10 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet1/Subnet (VPCAprivateSubnet1Subnet5428165A) SampleStack1 | 2/19 | 10:49:11 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet1/RouteTable (VPCAprivateSubnet1RouteTableE655FC72) Resource creation Initiated SampleStack1 | 2/19 | 10:49:11 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet1/RouteTable (VPCApublicSubnet1RouteTable2C204262) Resource creation Initiated SampleStack1 | 2/19 | 10:49:11 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet2/RouteTable (VPCAprivateSubnet2RouteTable796E6A86) Resource creation Initiated SampleStack1 | 2/19 | 10:49:12 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet2/RouteTable (VPCApublicSubnet2RouteTable2008F73C) Resource creation Initiated SampleStack1 | 2/19 | 10:49:12 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet2/Subnet (VPCAprivateSubnet2SubnetEF69CD95) Resource creation Initiated SampleStack1 | 2/19 | 10:49:12 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet1/Subnet (VPCAprivateSubnet1Subnet5428165A) Resource creation Initiated SampleStack1 | 2/19 | 10:49:12 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet2/Subnet (VPCApublicSubnet2Subnet8E975B94) Resource creation Initiated SampleStack1 | 2/19 | 10:49:12 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet1/Subnet (VPCApublicSubnet1SubnetCAE91A96) Resource creation Initiated SampleStack1 | 3/19 | 10:49:13 | CREATE_COMPLETE | AWS::EC2::InternetGateway | VPC_A/IGW (VPCAIGW75D87454) SampleStack1 | 3/19 | 10:49:14 | CREATE_IN_PROGRESS | AWS::EC2::VPCGatewayAttachment | VPC_A/VPCGW (VPCAVPCGWF4B02208) SampleStack1 | 4/19 | 10:49:14 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/privateSubnet2/Subnet (VPCAprivateSubnet2SubnetEF69CD95) SampleStack1 | 5/19 | 10:49:15 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/privateSubnet1/Subnet (VPCAprivateSubnet1Subnet5428165A) SampleStack1 | 5/19 | 10:49:15 | CREATE_IN_PROGRESS | AWS::EC2::VPCGatewayAttachment | VPC_A/VPCGW (VPCAVPCGWF4B02208) Resource creation Initiated SampleStack1 | 6/19 | 10:49:15 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/publicSubnet2/Subnet (VPCApublicSubnet2Subnet8E975B94) SampleStack1 | 7/19 | 10:49:15 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/publicSubnet1/Subnet (VPCApublicSubnet1SubnetCAE91A96) SampleStack1 | 8/19 | 10:49:21 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/privateSubnet1/RouteTable (VPCAprivateSubnet1RouteTableE655FC72) SampleStack1 | 9/19 | 10:49:22 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/publicSubnet1/RouteTable (VPCApublicSubnet1RouteTable2C204262) SampleStack1 | 9/19 | 10:49:23 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet1/RouteTableAssociation (VPCAprivateSubnet1RouteTableAssociation833A7203) SampleStack1 | 9/19 | 10:49:23 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet1/RouteTableAssociation (VPCApublicSubnet1RouteTableAssociation9C6FBB76) SampleStack1 | 9/19 | 10:49:24 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet1/RouteTableAssociation (VPCAprivateSubnet1RouteTableAssociation833A7203) Resource creation Initiated SampleStack1 | 10/19 | 10:49:25 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet1/RouteTableAssociation (VPCAprivateSubnet1RouteTableAssociation833A7203) SampleStack1 | 10/19 | 10:49:25 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet1/RouteTableAssociation (VPCApublicSubnet1RouteTableAssociation9C6FBB76) Resource creation Initiated SampleStack1 | 11/19 | 10:49:25 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet1/RouteTableAssociation (VPCApublicSubnet1RouteTableAssociation9C6FBB76) SampleStack1 | 12/19 | 10:49:27 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/publicSubnet2/RouteTable (VPCApublicSubnet2RouteTable2008F73C) SampleStack1 | 13/19 | 10:49:27 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/privateSubnet2/RouteTable (VPCAprivateSubnet2RouteTable796E6A86) SampleStack1 | 13/19 | 10:49:29 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet2/RouteTableAssociation (VPCAprivateSubnet2RouteTableAssociation9DBD3CEE) SampleStack1 | 13/19 | 10:49:29 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet2/RouteTableAssociation (VPCApublicSubnet2RouteTableAssociationBD5B656A) SampleStack1 | 14/19 | 10:49:30 | CREATE_COMPLETE | AWS::EC2::VPCGatewayAttachment | VPC_A/VPCGW (VPCAVPCGWF4B02208) SampleStack1 | 14/19 | 10:49:31 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet2/RouteTableAssociation (VPCApublicSubnet2RouteTableAssociationBD5B656A) Resource creation Initiated SampleStack1 | 14/19 | 10:49:31 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet2/RouteTableAssociation (VPCAprivateSubnet2RouteTableAssociation9DBD3CEE) Resource creation Initiated SampleStack1 | 15/19 | 10:49:31 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet2/RouteTableAssociation (VPCApublicSubnet2RouteTableAssociationBD5B656A) SampleStack1 | 16/19 | 10:49:31 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet2/RouteTableAssociation (VPCAprivateSubnet2RouteTableAssociation9DBD3CEE) SampleStack1 | 16/19 | 10:49:32 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet2/DefaultRoute (VPCApublicSubnet2DefaultRoute0A550678) SampleStack1 | 16/19 | 10:49:32 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet1/DefaultRoute (VPCApublicSubnet1DefaultRouteA342A3EF) SampleStack1 | 16/19 | 10:49:32 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet2/DefaultRoute (VPCApublicSubnet2DefaultRoute0A550678) Resource creation Initiated SampleStack1 | 16/19 | 10:49:32 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet1/DefaultRoute (VPCApublicSubnet1DefaultRouteA342A3EF) Resource creation Initiated SampleStack1 | 17/19 | 10:49:48 | CREATE_COMPLETE | AWS::EC2::Route | VPC_A/publicSubnet2/DefaultRoute (VPCApublicSubnet2DefaultRoute0A550678) SampleStack1 | 18/19 | 10:49:48 | CREATE_COMPLETE | AWS::EC2::Route | VPC_A/publicSubnet1/DefaultRoute (VPCApublicSubnet1DefaultRouteA342A3EF) SampleStack1 | 19/19 | 10:49:49 | CREATE_COMPLETE | AWS::CloudFormation::Stack | SampleStack1 ✅ SampleStack1 ✨ Deployment time: 78.03s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack1/aa51e320-d1c1-11ed-bd1b-0e3aaf94238b ✨ Total time: 80.94s
3つのスタックが並行でデプロイされ、実行時間が1分半程度になりました。直列デプロイに比べてだいぶ早くなっています。
並行デプロイの場合(上限並行数<スタック数)
では最大並行デプロイ数を2にするとどうなるでしょうか?
$ cdk deploy --all --concurrency 2 ✨ Synthesis time: 2.72s SampleStack1: building assets... [0%] start: Building db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region [100%] success: Built db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region SampleStack1: assets built SampleStack2: building assets... [0%] start: Building 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region [100%] success: Built 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region SampleStack2: assets built SampleStack3: building assets... [0%] start: Building 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region [100%] success: Built 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region SampleStack3: assets built SampleStack1 SampleStack2 SampleStack2: deploying... [2/3] SampleStack1: deploying... [1/3] [0%] start: Publishing db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region [0%] start: Publishing 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region [100%] success: Published db492062b83e12c3bd93a1aa7dda4982867afc87bbe8660c282b2a141c6b9645:current_account-current_region [100%] success: Published 9aa20d2393dc11946a175accab9a0e57c0028f4e2046a11b076dcadcf157e847:current_account-current_region SampleStack1: creating CloudFormation changeset... SampleStack2: creating CloudFormation changeset... SampleStack1 | 0/19 | 11:56:42 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack1 User Initiated SampleStack1 | 0/19 | 11:56:51 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack1 User Initiated SampleStack1 | 0/19 | 11:56:55 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack1 | 0/19 | 11:56:55 | CREATE_IN_PROGRESS | AWS::EC2::VPC | VPC_A (VPCAEF14CDB5) SampleStack1 | 0/19 | 11:56:55 | CREATE_IN_PROGRESS | AWS::EC2::InternetGateway | VPC_A/IGW (VPCAIGW75D87454) SampleStack1 | 0/19 | 11:56:56 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated SampleStack2 | 0/3 | 11:56:43 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack2 User Initiated SampleStack2 | 0/3 | 11:56:51 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack2 User Initiated SampleStack2 | 0/3 | 11:56:55 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack2 | 0/3 | 11:56:55 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable1 (SampleTable1E3EC8AE3) SampleStack2 | 0/3 | 11:56:56 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated SampleStack2 | 1/3 | 11:56:56 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack1 | 1/19 | 11:56:56 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack1 | 1/19 | 11:56:57 | CREATE_IN_PROGRESS | AWS::EC2::InternetGateway | VPC_A/IGW (VPCAIGW75D87454) Resource creation Initiated SampleStack1 | 1/19 | 11:56:57 | CREATE_IN_PROGRESS | AWS::EC2::VPC | VPC_A (VPCAEF14CDB5) Resource creation Initiated SampleStack2 | 1/3 | 11:56:57 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable1 (SampleTable1E3EC8AE3) Resource creation Initiated SampleStack1 | 2/19 | 11:57:08 | CREATE_COMPLETE | AWS::EC2::VPC | VPC_A (VPCAEF14CDB5) SampleStack2 | 2/3 | 11:57:07 | CREATE_COMPLETE | AWS::DynamoDB::Table | SampleTable1 (SampleTable1E3EC8AE3) SampleStack2 | 3/3 | 11:57:08 | CREATE_COMPLETE | AWS::CloudFormation::Stack | SampleStack2 ✅ SampleStack2 ✨ Deployment time: 34.95s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack2/29c55d40-d1cb-11ed-bbb2-129b30686da3 ✨ Total time: 37.67s SampleStack3 SampleStack3: deploying... [3/3] SampleStack1 | 2/19 | 11:57:10 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet1/RouteTable (VPCAprivateSubnet1RouteTableE655FC72) SampleStack1 | 2/19 | 11:57:10 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet2/RouteTable (VPCAprivateSubnet2RouteTable796E6A86) SampleStack1 | 2/19 | 11:57:10 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet2/RouteTable (VPCApublicSubnet2RouteTable2008F73C) SampleStack1 | 2/19 | 11:57:10 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet1/RouteTable (VPCApublicSubnet1RouteTable2C204262) SampleStack1 | 2/19 | 11:57:10 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet2/Subnet (VPCApublicSubnet2Subnet8E975B94) SampleStack1 | 2/19 | 11:57:10 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet1/Subnet (VPCApublicSubnet1SubnetCAE91A96) SampleStack1 | 2/19 | 11:57:10 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet1/Subnet (VPCAprivateSubnet1Subnet5428165A) SampleStack1 | 2/19 | 11:57:10 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet2/Subnet (VPCAprivateSubnet2SubnetEF69CD95) SampleStack1 | 2/19 | 11:57:11 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet1/RouteTable (VPCAprivateSubnet1RouteTableE655FC72) Resource creation Initiated SampleStack1 | 2/19 | 11:57:11 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet2/RouteTable (VPCAprivateSubnet2RouteTable796E6A86) Resource creation Initiated SampleStack1 | 2/19 | 11:57:11 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet2/RouteTable (VPCApublicSubnet2RouteTable2008F73C) Resource creation Initiated SampleStack1 | 2/19 | 11:57:11 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet1/RouteTable (VPCApublicSubnet1RouteTable2C204262) Resource creation Initiated SampleStack1 | 2/19 | 11:57:12 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet2/Subnet (VPCAprivateSubnet2SubnetEF69CD95) Resource creation Initiated SampleStack1 | 2/19 | 11:57:12 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet2/Subnet (VPCApublicSubnet2Subnet8E975B94) Resource creation Initiated SampleStack1 | 2/19 | 11:57:12 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet1/Subnet (VPCAprivateSubnet1Subnet5428165A) Resource creation Initiated SampleStack1 | 3/19 | 11:57:12 | CREATE_COMPLETE | AWS::EC2::InternetGateway | VPC_A/IGW (VPCAIGW75D87454) SampleStack1 | 3/19 | 11:57:12 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet1/Subnet (VPCApublicSubnet1SubnetCAE91A96) Resource creation Initiated SampleStack1 | 3/19 | 11:57:14 | CREATE_IN_PROGRESS | AWS::EC2::VPCGatewayAttachment | VPC_A/VPCGW (VPCAVPCGWF4B02208) [0%] start: Publishing 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region [100%] success: Published 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region SampleStack3: creating CloudFormation changeset... SampleStack1 | 4/19 | 11:57:14 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/privateSubnet2/Subnet (VPCAprivateSubnet2SubnetEF69CD95) SampleStack1 | 4/19 | 11:57:14 | CREATE_IN_PROGRESS | AWS::EC2::VPCGatewayAttachment | VPC_A/VPCGW (VPCAVPCGWF4B02208) Resource creation Initiated SampleStack1 | 5/19 | 11:57:15 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/publicSubnet2/Subnet (VPCApublicSubnet2Subnet8E975B94) SampleStack1 | 6/19 | 11:57:15 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/publicSubnet1/Subnet (VPCApublicSubnet1SubnetCAE91A96) SampleStack1 | 7/19 | 11:57:15 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/privateSubnet1/Subnet (VPCAprivateSubnet1Subnet5428165A) SampleStack1 | 8/19 | 11:57:22 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/publicSubnet2/RouteTable (VPCApublicSubnet2RouteTable2008F73C) SampleStack1 | 9/19 | 11:57:22 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/privateSubnet2/RouteTable (VPCAprivateSubnet2RouteTable796E6A86) SampleStack1 | 10/19 | 11:57:22 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/publicSubnet1/RouteTable (VPCApublicSubnet1RouteTable2C204262) SampleStack1 | 10/19 | 11:57:23 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet2/RouteTableAssociation (VPCAprivateSubnet2RouteTableAssociation9DBD3CEE) SampleStack1 | 10/19 | 11:57:23 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet2/RouteTableAssociation (VPCApublicSubnet2RouteTableAssociationBD5B656A) SampleStack1 | 10/19 | 11:57:23 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet1/RouteTableAssociation (VPCApublicSubnet1RouteTableAssociation9C6FBB76) SampleStack1 | 10/19 | 11:57:24 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet2/RouteTableAssociation (VPCAprivateSubnet2RouteTableAssociation9DBD3CEE) Resource creation Initiated SampleStack1 | 10/19 | 11:57:24 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet2/RouteTableAssociation (VPCApublicSubnet2RouteTableAssociationBD5B656A) Resource creation Initiated SampleStack1 | 11/19 | 11:57:25 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet2/RouteTableAssociation (VPCApublicSubnet2RouteTableAssociationBD5B656A) SampleStack1 | 12/19 | 11:57:25 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet2/RouteTableAssociation (VPCAprivateSubnet2RouteTableAssociation9DBD3CEE) SampleStack1 | 12/19 | 11:57:25 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet1/RouteTableAssociation (VPCApublicSubnet1RouteTableAssociation9C6FBB76) Resource creation Initiated SampleStack1 | 13/19 | 11:57:26 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet1/RouteTableAssociation (VPCApublicSubnet1RouteTableAssociation9C6FBB76) SampleStack1 | 14/19 | 11:57:27 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/privateSubnet1/RouteTable (VPCAprivateSubnet1RouteTableE655FC72) SampleStack1 | 14/19 | 11:57:29 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet1/RouteTableAssociation (VPCAprivateSubnet1RouteTableAssociation833A7203) SampleStack1 | 15/19 | 11:57:30 | CREATE_COMPLETE | AWS::EC2::VPCGatewayAttachment | VPC_A/VPCGW (VPCAVPCGWF4B02208) SampleStack1 | 15/19 | 11:57:31 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet1/RouteTableAssociation (VPCAprivateSubnet1RouteTableAssociation833A7203) Resource creation Initiated SampleStack1 | 16/19 | 11:57:31 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet1/RouteTableAssociation (VPCAprivateSubnet1RouteTableAssociation833A7203) SampleStack1 | 16/19 | 11:57:31 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet1/DefaultRoute (VPCApublicSubnet1DefaultRouteA342A3EF) SampleStack1 | 16/19 | 11:57:31 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet2/DefaultRoute (VPCApublicSubnet2DefaultRoute0A550678) SampleStack1 | 16/19 | 11:57:32 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet1/DefaultRoute (VPCApublicSubnet1DefaultRouteA342A3EF) Resource creation Initiated SampleStack1 | 16/19 | 11:57:32 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet2/DefaultRoute (VPCApublicSubnet2DefaultRoute0A550678) Resource creation Initiated SampleStack3 | 0/3 | 11:57:20 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack3 User Initiated SampleStack3 | 0/3 | 11:57:28 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack3 User Initiated SampleStack3 | 0/3 | 11:57:32 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack3 | 0/3 | 11:57:32 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable2 (SampleTable283919C1B) SampleStack3 | 0/3 | 11:57:34 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable2 (SampleTable283919C1B) Resource creation Initiated SampleStack3 | 0/3 | 11:57:34 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated SampleStack3 | 1/3 | 11:57:34 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack3 | 2/3 | 11:57:44 | CREATE_COMPLETE | AWS::DynamoDB::Table | SampleTable2 (SampleTable283919C1B) SampleStack3 | 3/3 | 11:57:46 | CREATE_COMPLETE | AWS::CloudFormation::Stack | SampleStack3 ✅ SampleStack3 ✨ Deployment time: 34.74s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack3/403e89c0-d1cb-11ed-b6af-0ebdd50288cf ✨ Total time: 37.46s SampleStack1 | 17/19 | 11:57:47 | CREATE_COMPLETE | AWS::EC2::Route | VPC_A/publicSubnet1/DefaultRoute (VPCApublicSubnet1DefaultRouteA342A3EF) SampleStack1 | 18/19 | 11:57:48 | CREATE_COMPLETE | AWS::EC2::Route | VPC_A/publicSubnet2/DefaultRoute (VPCApublicSubnet2DefaultRoute0A550678) SampleStack1 | 19/19 | 11:57:49 | CREATE_COMPLETE | AWS::CloudFormation::Stack | SampleStack1 ✅ SampleStack1 ✨ Deployment time: 76.54s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack1/29a244e0-d1cb-11ed-8102-0a7a32ebd56b ✨ Total time: 79.26s
ログからは分かりづらいですが、2つのスタック(SampleStack1, SampleStack2)が先にデプロイが開始され、どちらかのスタック(今回はSampleStack2)のデプロイ完了後に3つ目のスタック(SampleStack3)のデプロイが始まっています。
多数のリソースが作成される場合、レートリミットを考慮して上限を低めに設定すると良いでしょう。
依存関係のある複数スタック並行デプロイの場合
最後にスタック間の依存関係がある場合です。
SampleStack2がSampleStack1に依存するよう、以下のようにCDKのコードを変更します。
import * as cdk from "aws-cdk-lib"; import { Construct } from "constructs"; import * as ec2 from "aws-cdk-lib/aws-ec2"; import * as dynamo from "aws-cdk-lib/aws-dynamodb"; export class SampleStack1 extends cdk.Stack { public readonly vpc: ec2.Vpc; constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); this.vpc = new ec2.Vpc(this, "VPC_A", { ipAddresses: ec2.IpAddresses.cidr("10.1.0.0/16"), subnetConfiguration: [ { cidrMask: 24, name: "public", subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: "private", subnetType: ec2.SubnetType.PRIVATE_ISOLATED, }, ], }); } } interface SampleStack2Props extends cdk.StackProps { vpc: ec2.Vpc; } export class SampleStack2 extends cdk.Stack { constructor(scope: Construct, id: string, props: SampleStack2Props) { super(scope, id, props); new dynamo.Table(this, "SampleTable1", { tableName: "SampleTable1", billingMode: dynamo.BillingMode.PAY_PER_REQUEST, partitionKey: { name: "id", type: dynamo.AttributeType.STRING, }, removalPolicy: cdk.RemovalPolicy.DESTROY, }); new ec2.Instance(this, "SampleEC2Instance", { vpc: props.vpc, instanceType: ec2.InstanceType.of( ec2.InstanceClass.T3, ec2.InstanceSize.MICRO ), machineImage: new ec2.AmazonLinuxImage(), }); } } export class SampleStack3 extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new dynamo.Table(this, "SampleTable2", { tableName: "SampleTable2", billingMode: dynamo.BillingMode.PAY_PER_REQUEST, partitionKey: { name: "id", type: dynamo.AttributeType.STRING, }, removalPolicy: cdk.RemovalPolicy.DESTROY, }); } }
#!/usr/bin/env node import "source-map-support/register"; import * as cdk from "aws-cdk-lib"; import { SampleStack1, SampleStack2, SampleStack3, } from "../lib/cdk-multi-deploy-sample-stack"; const app = new cdk.App(); const stack1 = new SampleStack1(app, "SampleStack1"); new SampleStack2(app, "SampleStack2", { vpc: stack1.vpc }); new SampleStack3(app, "SampleStack3");
この場合、SampleStack1がデプロイされたあとにSampleStack2がデプロイされる必要があります。
デプロイを行って、想定通りの順序でデプロイが行われるか確認します。
EC2(にアタッチするセキュリティグループ)の作成の承認を無視するため、今回のみ--require-approval
オプションを指定しています。(このオプションを指定しない場合はエラーとなり、デプロイできません。)
cdk deploy --all --require-approval never --concurrency 3 ✨ Synthesis time: 3.04s SampleStack1: building assets... [0%] start: Building 91c7ea692437eca46b346f15e31203a58655905896d5613f847a767698081f24:current_account-current_region [100%] success: Built 91c7ea692437eca46b346f15e31203a58655905896d5613f847a767698081f24:current_account-current_region SampleStack1: assets built SampleStack3: building assets... [0%] start: Building 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region [100%] success: Built 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region SampleStack3: assets built SampleStack2: building assets... [0%] start: Building 7c33633358050e3ecfbd71ca8f40d12c364bb6fcd71338a52f100d27ae81d00b:current_account-current_region [100%] success: Built 7c33633358050e3ecfbd71ca8f40d12c364bb6fcd71338a52f100d27ae81d00b:current_account-current_region SampleStack2: assets built SampleStack1 SampleStack1: deploying... [1/3] SampleStack3 SampleStack3: deploying... [2/3] [0%] start: Publishing 91c7ea692437eca46b346f15e31203a58655905896d5613f847a767698081f24:current_account-current_region [0%] start: Publishing 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region [100%] success: Published 6cd9bcd505a1a584297e82e46762cabbc84dfbcf30c4d5455d2c8ac9e2e18dfb:current_account-current_region [100%] success: Published 91c7ea692437eca46b346f15e31203a58655905896d5613f847a767698081f24:current_account-current_region SampleStack3: creating CloudFormation changeset... SampleStack1: creating CloudFormation changeset... SampleStack3 | 0/3 | 16:13:53 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack3 User Initiated SampleStack3 | 0/3 | 16:14:00 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack3 User Initiated SampleStack3 | 0/3 | 16:14:05 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable2 (SampleTable283919C1B) SampleStack3 | 0/3 | 16:14:05 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack1 | 0/19 | 16:13:53 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack1 User Initiated SampleStack1 | 0/19 | 16:14:01 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack1 User Initiated SampleStack1 | 0/19 | 16:14:05 | CREATE_IN_PROGRESS | AWS::EC2::VPC | VPC_A (VPCAEF14CDB5) SampleStack1 | 0/19 | 16:14:05 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack1 | 0/19 | 16:14:05 | CREATE_IN_PROGRESS | AWS::EC2::InternetGateway | VPC_A/IGW (VPCAIGW75D87454) SampleStack1 | 0/19 | 16:14:06 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated SampleStack1 | 1/19 | 16:14:07 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack3 | 0/3 | 16:14:06 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable2 (SampleTable283919C1B) Resource creation Initiated SampleStack3 | 0/3 | 16:14:07 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated SampleStack3 | 1/3 | 16:14:07 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack1 | 1/19 | 16:14:07 | CREATE_IN_PROGRESS | AWS::EC2::InternetGateway | VPC_A/IGW (VPCAIGW75D87454) Resource creation Initiated SampleStack1 | 1/19 | 16:14:07 | CREATE_IN_PROGRESS | AWS::EC2::VPC | VPC_A (VPCAEF14CDB5) Resource creation Initiated SampleStack3 | 2/3 | 16:14:17 | CREATE_COMPLETE | AWS::DynamoDB::Table | SampleTable2 (SampleTable283919C1B) SampleStack3 | 3/3 | 16:14:18 | CREATE_COMPLETE | AWS::CloudFormation::Stack | SampleStack3 ✅ SampleStack3 ✨ Deployment time: 34.69s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack3/16cf59b0-d1ef-11ed-80af-129f65a22c75 ✨ Total time: 37.73s SampleStack1 | 2/19 | 16:14:19 | CREATE_COMPLETE | AWS::EC2::VPC | VPC_A (VPCAEF14CDB5) SampleStack1 | 2/19 | 16:14:20 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet2/RouteTable (VPCAprivateSubnet2RouteTable796E6A86) SampleStack1 | 2/19 | 16:14:20 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet1/RouteTable (VPCAprivateSubnet1RouteTableE655FC72) SampleStack1 | 2/19 | 16:14:20 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet1/RouteTable (VPCApublicSubnet1RouteTable2C204262) SampleStack1 | 2/19 | 16:14:20 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet2/Subnet (VPCAprivateSubnet2SubnetEF69CD95) SampleStack1 | 2/19 | 16:14:20 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet2/RouteTable (VPCApublicSubnet2RouteTable2008F73C) SampleStack1 | 2/19 | 16:14:21 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet2/Subnet (VPCApublicSubnet2Subnet8E975B94) SampleStack1 | 2/19 | 16:14:21 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet1/Subnet (VPCAprivateSubnet1Subnet5428165A) SampleStack1 | 2/19 | 16:14:21 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet1/Subnet (VPCApublicSubnet1SubnetCAE91A96) SampleStack1 | 2/19 | 16:14:21 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet2/RouteTable (VPCAprivateSubnet2RouteTable796E6A86) Resource creation Initiated SampleStack1 | 2/19 | 16:14:22 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet1/RouteTable (VPCApublicSubnet1RouteTable2C204262) Resource creation Initiated SampleStack1 | 2/19 | 16:14:22 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/privateSubnet1/RouteTable (VPCAprivateSubnet1RouteTableE655FC72) Resource creation Initiated SampleStack1 | 2/19 | 16:14:22 | CREATE_IN_PROGRESS | AWS::EC2::RouteTable | VPC_A/publicSubnet2/RouteTable (VPCApublicSubnet2RouteTable2008F73C) Resource creation Initiated SampleStack1 | 2/19 | 16:14:22 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet2/Subnet (VPCAprivateSubnet2SubnetEF69CD95) Resource creation Initiated SampleStack1 | 2/19 | 16:14:22 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet1/Subnet (VPCApublicSubnet1SubnetCAE91A96) Resource creation Initiated SampleStack1 | 3/19 | 16:14:23 | CREATE_COMPLETE | AWS::EC2::InternetGateway | VPC_A/IGW (VPCAIGW75D87454) SampleStack1 | 3/19 | 16:14:23 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/privateSubnet1/Subnet (VPCAprivateSubnet1Subnet5428165A) Resource creation Initiated SampleStack1 | 3/19 | 16:14:23 | CREATE_IN_PROGRESS | AWS::EC2::Subnet | VPC_A/publicSubnet2/Subnet (VPCApublicSubnet2Subnet8E975B94) Resource creation Initiated SampleStack1 | 3/19 | 16:14:24 | CREATE_IN_PROGRESS | AWS::EC2::VPCGatewayAttachment | VPC_A/VPCGW (VPCAVPCGWF4B02208) SampleStack1 | 3/19 | 16:14:24 | CREATE_IN_PROGRESS | AWS::EC2::VPCGatewayAttachment | VPC_A/VPCGW (VPCAVPCGWF4B02208) Resource creation Initiated SampleStack1 | 4/19 | 16:14:25 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/privateSubnet2/Subnet (VPCAprivateSubnet2SubnetEF69CD95) SampleStack1 | 5/19 | 16:14:25 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/privateSubnet1/Subnet (VPCAprivateSubnet1Subnet5428165A) SampleStack1 | 6/19 | 16:14:26 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/publicSubnet1/Subnet (VPCApublicSubnet1SubnetCAE91A96) SampleStack1 | 7/19 | 16:14:26 | CREATE_COMPLETE | AWS::EC2::Subnet | VPC_A/publicSubnet2/Subnet (VPCApublicSubnet2Subnet8E975B94) SampleStack1 | 8/19 | 16:14:32 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/privateSubnet2/RouteTable (VPCAprivateSubnet2RouteTable796E6A86) SampleStack1 | 9/19 | 16:14:32 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/publicSubnet1/RouteTable (VPCApublicSubnet1RouteTable2C204262) SampleStack1 | 10/19 | 16:14:32 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/privateSubnet1/RouteTable (VPCAprivateSubnet1RouteTableE655FC72) SampleStack1 | 11/19 | 16:14:32 | CREATE_COMPLETE | AWS::EC2::RouteTable | VPC_A/publicSubnet2/RouteTable (VPCApublicSubnet2RouteTable2008F73C) SampleStack1 | 11/19 | 16:14:33 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet2/RouteTableAssociation (VPCAprivateSubnet2RouteTableAssociation9DBD3CEE) SampleStack1 | 11/19 | 16:14:34 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet1/RouteTableAssociation (VPCApublicSubnet1RouteTableAssociation9C6FBB76) SampleStack1 | 11/19 | 16:14:34 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet2/RouteTableAssociation (VPCApublicSubnet2RouteTableAssociationBD5B656A) SampleStack1 | 11/19 | 16:14:34 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet1/RouteTableAssociation (VPCAprivateSubnet1RouteTableAssociation833A7203) SampleStack1 | 11/19 | 16:14:35 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet2/RouteTableAssociation (VPCAprivateSubnet2RouteTableAssociation9DBD3CEE) Resource creation Initiated SampleStack1 | 11/19 | 16:14:35 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet1/RouteTableAssociation (VPCApublicSubnet1RouteTableAssociation9C6FBB76) Resource creation Initiated SampleStack1 | 11/19 | 16:14:35 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet2/RouteTableAssociation (VPCApublicSubnet2RouteTableAssociationBD5B656A) Resource creation Initiated SampleStack1 | 12/19 | 16:14:36 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet1/RouteTableAssociation (VPCApublicSubnet1RouteTableAssociation9C6FBB76) SampleStack1 | 13/19 | 16:14:36 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/publicSubnet2/RouteTableAssociation (VPCApublicSubnet2RouteTableAssociationBD5B656A) SampleStack1 | 13/19 | 16:14:36 | CREATE_IN_PROGRESS | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet1/RouteTableAssociation (VPCAprivateSubnet1RouteTableAssociation833A7203) Resource creation Initiated SampleStack1 | 14/19 | 16:14:36 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet1/RouteTableAssociation (VPCAprivateSubnet1RouteTableAssociation833A7203) SampleStack1 | 15/19 | 16:14:40 | CREATE_COMPLETE | AWS::EC2::VPCGatewayAttachment | VPC_A/VPCGW (VPCAVPCGWF4B02208) SampleStack1 | 15/19 | 16:14:41 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet2/DefaultRoute (VPCApublicSubnet2DefaultRoute0A550678) SampleStack1 | 15/19 | 16:14:42 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet1/DefaultRoute (VPCApublicSubnet1DefaultRouteA342A3EF) SampleStack1 | 15/19 | 16:14:42 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet2/DefaultRoute (VPCApublicSubnet2DefaultRoute0A550678) Resource creation Initiated SampleStack1 | 15/19 | 16:14:42 | CREATE_IN_PROGRESS | AWS::EC2::Route | VPC_A/publicSubnet1/DefaultRoute (VPCApublicSubnet1DefaultRouteA342A3EF) Resource creation Initiated SampleStack1 | 16/19 | 16:14:45 | CREATE_COMPLETE | AWS::EC2::SubnetRouteTableAssociation | VPC_A/privateSubnet2/RouteTableAssociation (VPCAprivateSubnet2RouteTableAssociation9DBD3CEE) SampleStack1 | 17/19 | 16:14:58 | CREATE_COMPLETE | AWS::EC2::Route | VPC_A/publicSubnet2/DefaultRoute (VPCApublicSubnet2DefaultRoute0A550678) SampleStack1 | 18/19 | 16:14:58 | CREATE_COMPLETE | AWS::EC2::Route | VPC_A/publicSubnet1/DefaultRoute (VPCApublicSubnet1DefaultRouteA342A3EF) SampleStack1 | 19/19 | 16:15:00 | CREATE_COMPLETE | AWS::CloudFormation::Stack | SampleStack1 ✅ SampleStack1 ✨ Deployment time: 77.12s Outputs: SampleStack1.ExportsOutputRefVPCAEF14CDB53F68D3CF = vpc-068222553cacd6cf7 SampleStack1.ExportsOutputRefVPCAprivateSubnet1Subnet5428165ACB45B59D = subnet-00e76d51e20427a7d Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack1/16d96bd0-d1ef-11ed-a4fb-12b5f657b2a1 ✨ Total time: 80.16s SampleStack2 SampleStack2: deploying... [3/3] [0%] start: Publishing 7c33633358050e3ecfbd71ca8f40d12c364bb6fcd71338a52f100d27ae81d00b:current_account-current_region [100%] success: Published 7c33633358050e3ecfbd71ca8f40d12c364bb6fcd71338a52f100d27ae81d00b:current_account-current_region SampleStack2: creating CloudFormation changeset... SampleStack2 | 0/7 | 16:15:13 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack2 User Initiated SampleStack2 | 0/7 | 16:15:21 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | SampleStack2 User Initiated SampleStack2 | 0/7 | 16:15:24 | CREATE_IN_PROGRESS | AWS::IAM::Role | SampleEC2Instance/InstanceRole (SampleEC2InstanceInstanceRoleF9B4605D) SampleStack2 | 0/7 | 16:15:25 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable1 (SampleTable1E3EC8AE3) SampleStack2 | 0/7 | 16:15:25 | CREATE_IN_PROGRESS | AWS::IAM::Role | SampleEC2Instance/InstanceRole (SampleEC2InstanceInstanceRoleF9B4605D) Resource creation Initiated SampleStack2 | 0/7 | 16:15:25 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack2 | 0/7 | 16:15:25 | CREATE_IN_PROGRESS | AWS::EC2::SecurityGroup | SampleEC2Instance/InstanceSecurityGroup (SampleEC2InstanceInstanceSecurityGroupF6680F06) SampleStack2 | 0/7 | 16:15:26 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated SampleStack2 | 1/7 | 16:15:26 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) SampleStack2 | 1/7 | 16:15:26 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | SampleTable1 (SampleTable1E3EC8AE3) Resource creation Initiated SampleStack2 | 1/7 | 16:15:30 | CREATE_IN_PROGRESS | AWS::EC2::SecurityGroup | SampleEC2Instance/InstanceSecurityGroup (SampleEC2InstanceInstanceSecurityGroupF6680F06) Resource creation Initiated SampleStack2 | 2/7 | 16:15:31 | CREATE_COMPLETE | AWS::EC2::SecurityGroup | SampleEC2Instance/InstanceSecurityGroup (SampleEC2InstanceInstanceSecurityGroupF6680F06) SampleStack2 | 3/7 | 16:15:38 | CREATE_COMPLETE | AWS::DynamoDB::Table | SampleTable1 (SampleTable1E3EC8AE3) SampleStack2 | 4/7 | 16:15:38 | CREATE_COMPLETE | AWS::IAM::Role | SampleEC2Instance/InstanceRole (SampleEC2InstanceInstanceRoleF9B4605D) SampleStack2 | 4/7 | 16:15:40 | CREATE_IN_PROGRESS | AWS::IAM::InstanceProfile | SampleEC2Instance/InstanceProfile (SampleEC2InstanceInstanceProfileA3EB8717) SampleStack2 | 4/7 | 16:15:41 | CREATE_IN_PROGRESS | AWS::IAM::InstanceProfile | SampleEC2Instance/InstanceProfile (SampleEC2InstanceInstanceProfileA3EB8717) Resource creation Initiated 4/7 Currently in progress: SampleStack2, SampleEC2InstanceInstanceProfileA3EB8717 SampleStack2 | 5/7 | 16:17:52 | CREATE_COMPLETE | AWS::IAM::InstanceProfile | SampleEC2Instance/InstanceProfile (SampleEC2InstanceInstanceProfileA3EB8717) SampleStack2 | 5/7 | 16:17:54 | CREATE_IN_PROGRESS | AWS::EC2::Instance | SampleEC2Instance (SampleEC2InstanceDE2B2B81) SampleStack2 | 5/7 | 16:17:56 | CREATE_IN_PROGRESS | AWS::EC2::Instance | SampleEC2Instance (SampleEC2InstanceDE2B2B81) Resource creation Initiated SampleStack2 | 6/7 | 16:18:03 | CREATE_COMPLETE | AWS::EC2::Instance | SampleEC2Instance (SampleEC2InstanceDE2B2B81) SampleStack2 | 7/7 | 16:18:05 | CREATE_COMPLETE | AWS::CloudFormation::Stack | SampleStack2 ✅ SampleStack2 ✨ Deployment time: 186.27s Stack ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack2/9e2dd9a0-d1ee-11ed-ae15-12ef5f00c7e7 ✨ Total time: 189.3s
concurrencyオプションで並行実行数は3としましたが、
1. SampleStack1,3をデプロイ
2. SampleStack1のデプロイ完了後にSampleStack2をデプロイ
という動作になっています。
自動的に依存関係が解決され、可能な部分で並行実行されていることがわかります。
さいごに
今回は並行デプロイ方法についてご紹介しました。
複数スタックを直列デプロイされている方、この機会に並行デプロイを試してみてはいかがでしょうか?
以上、八木でした!